﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Data;
using System.IO.Compression;
using Microsoft.ApplicationBlocks.Data;
using System.Data.SqlClient;
using System.Transactions;
using System.Configuration;
using Common;

namespace SCMWS
{
    /// <summary>
    /// SyncDB の概要の説明です
    /// </summary>
    [WebService(Namespace = "http://rv-scm.org/WebService")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // この Web サービスを、スクリプトから ASP.NET AJAX を使用して呼び出せるようにするには、次の行のコメントを解除します。 
    // [System.Web.Script.Services.ScriptService]
    public class SyncDB : System.Web.Services.WebService
    {


        [WebMethod(Description = "Send shop data to remote ")]
        public int SendShopData(byte[] shopData)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = DeCompress(shopData);
            object obj = bf.Deserialize(ms);
            //DataSetSurrogate dss = (DataSetSurrogate)obj;
            ms.Close();
            //DataSet ds = dss.ConvertToDataSet();
            DataSet ds = (DataSet)obj;
            //Save Recived Data to ShopTable
            SaveToSupplierTab(ds);
            // return the Result 
            return 0;
        }

        [WebMethod(Description = "获取业务资料远程DATASET")]
        public byte[] SurrogateRead1()
        {
            byte[] bArrayResult = null;
            DataSet ds;
            try
            {
                using (SqlConnection cn = GetConnection(ConfigurationManager.ConnectionStrings["supnetdb"].ConnectionString))
                {
                    ds = SqlHelper.ExecuteDataset(cn, CommandType.Text, "select * from D_Accounting");
                    //DataSetSurrogate dss = new DataSetSurrogate(ds);
                    MemoryStream ms = new MemoryStream();
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(ms, ds);

                    bArrayResult = Compress(ms.ToArray());
                    ms.Close();
                }
            }
            catch(Exception)
            {
            }
            return bArrayResult;

        }

        #region Utility 

        /// <summary>
        /// 压缩数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private byte[] Compress(byte[] data)
        {
            MemoryStream ms = new MemoryStream();
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress);
            zipStream.Write(data, 0, data.Length);
            zipStream.Close();
            return ms.ToArray();
        }

        /// <summary>
        /// 解压数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private MemoryStream DeCompress(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
            MemoryStream outms = new MemoryStream();

            byte[] buffer = new byte[1024];
            while (true)
            {
                int readSize = zipStream.Read(buffer, 0, buffer.Length);
               
                if (readSize == 0)
                    break;
                outms.Write(buffer, 0, readSize);
            }
            zipStream.Close();
            ms.Close();
            outms.Position = 0;
            return outms;
        }
        /// <summary>
        /// 建立数据库连接
        /// </summary>
        /// <param name="connectionString"></param>
        /// <returns></returns>
        private SqlConnection GetConnection(string connectionString)
        {
            SqlConnection connection = new SqlConnection(connectionString);
            connection.Open();

            return connection;
        }
        #endregion

        #region 使用SqlBulkCopy
        private bool ExecuteTransactionScopeInsert(SqlConnection cn, DataTable dt, String tableName,int batchSize)
        {
            int count = dt.Rows.Count;
           
            int copyTimeout = 600;
            bool flag = false;
            try
            {
                using (SqlBulkCopy sbc = new SqlBulkCopy(cn))
                {
                    //服务器上目标表的名称     
                    sbc.DestinationTableName = tableName;
                    sbc.BatchSize = batchSize;
                    sbc.BulkCopyTimeout = copyTimeout;
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        //列映射定义数据源中的列和目标表中的列之间的关系     
                        sbc.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
                    }
                    sbc.WriteToServer(dt);
                    flag = true;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("SqlBulkCopy Insert", ex);
                return false;
            }
            return flag;
        }
        #endregion  

        #region Save supplier info
        /// <summary>
        /// Save Supplier infor
        /// </summary>
        /// <param name="dsInput"></param>
        /// <returns></returns>
        private int SaveToSupplierTab(DataSet dsInput)
        {
            int savedRecord = 0;
            if (dsInput != null && dsInput.Tables.Count > 0)
            {
                try
                {
                    using (SqlConnection cn = GetConnection(ConfigurationManager.ConnectionStrings["supnetdb"].ConnectionString))
                    {
                        cn.Open();
                        using (TransactionScope scope = new TransactionScope())
                        {
                            //Clear TMP_M_Supplier
                            SqlHelper.ExecuteNonQuery(cn, CommandType.Text, "TRUNCATE TABLE TMP_M_Supplier");
                            //insert data to temptable
                            ExecuteTransactionScopeInsert(cn,dsInput.Tables[0], "TMP_M_Supplier", 600);
                            //Clear M_Supplier
                            SqlHelper.ExecuteNonQuery(cn, CommandType.Text, "TRUNCATE TABLE M_Supplier");
                            //copy data to M_Supplier
                            SqlHelper.ExecuteNonQuery(cn, CommandType.Text, "INSERT INTO M_Supplier SELECT * FROM TMP_M_Supplier");

                            scope.Complete();
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error("Failure to save Supplier", ex);
                }

            }
            else
            {
                LogHelper.Info("Not exsit Data.");
            }
            return savedRecord;
        }
        #endregion
    }
}
